home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / By the Book / Mac Pascal Primer, 4.0 / Chap 6, Reminder ƒ / Reminder.p next >
Text File  |  1991-08-23  |  14KB  |  548 lines

  1. program Reminder;
  2.     uses
  3.         Notification;
  4.  
  5.     const
  6.         BASE_RES_ID = 400;
  7.         ABOUT_ALERT = 401;
  8.         BAD_SYS_ALERT = 402;
  9.  
  10.         MIN_SLEEP = 0;
  11.  
  12.         DRAG_THRESHOLD = 30;
  13.  
  14.         SAVE_BUTTON = 1;
  15.         CANCEL_BUTTON = 2;
  16.         TIME_FIELD = 4;
  17.         S_OR_M_FIELD = 5;
  18.         SOUND_ON_BOX = 6;
  19.         ICON_ON_BOX = 7;
  20.         ALERT_ON_BOX = 8;
  21.         SECS_RADIO = 10;
  22.         MINS_RADIO = 11;
  23.  
  24.         DEFAULT_SECS_ID = 401;
  25.         DEFAULT_MINS_ID = 402;
  26.  
  27.         ON = 1;
  28.         OFF = 0;
  29.  
  30.         SECONDS_PER_MINUTE = 60;
  31.  
  32.         TOP = 25;
  33.         LEFT = 12;
  34.  
  35.         MARK_APPLICATION = 1;
  36.  
  37.         APPLE_MENU_ID = BASE_RES_ID;
  38.         FILE_MENU_ID = BASE_RES_ID + 1;
  39.         ABOUT_ITEM = 1;
  40.  
  41.         CHANGE_ITEM = 1;
  42.         START_STOP_ITEM = 2;
  43.         KILL_ITEM = 3;
  44.         QUIT_ITEM = 4;
  45.  
  46.         SYS_VERSION = 2;
  47.  
  48.     type
  49.         settings = record
  50.                 timeString: Str255;
  51.                 sound, icon, alert, secsRadio, minsRadio: INTEGER;
  52.             end;
  53.  
  54.     var
  55.         gSettingsDialog: DialogPtr;
  56.         gDragRect: Rect;
  57.         gDone, gCounting, gNotify_set: BOOLEAN;
  58.         gSeconds_or_minutes: (seconds, minutes);
  59.         gNotifyStrH, gDefaultSecsH, gDefaultMinsH: StringHandle;
  60.         gMyNMRec: NMRec;
  61.         gAppleMenu, gFileMenu: MenuHandle;
  62.         gTheEvent: EventRecord;
  63.         savedSettings: settings;
  64.  
  65.  
  66.     procedure HandleEvent;
  67.     forward;
  68.  
  69.  
  70. {-------------------------------->    SetNotification    <---}
  71.  
  72.     procedure SetNotification;
  73.         var
  74.             itemType: INTEGER;
  75.             itemRect: Rect;
  76.             itemHandle: Handle;
  77.             dummy: OSErr;
  78.     begin
  79.         if gNotify_set then
  80.             begin
  81.                 dummy := NMRemove(@gMyNMRec);
  82.                 HUnlock(Handle(gNotifyStrH));
  83.             end;
  84.  
  85.         GetDItem(gSettingsDialog, ICON_ON_BOX, itemType, itemHandle, itemRect);
  86.         if GetCtlValue(ControlHandle(itemHandle)) = ON then
  87.             gMyNMRec.nmIcon := GetResource('SICN', BASE_RES_ID)
  88.         else
  89.             gMyNMRec.nmIcon := nil;
  90.  
  91.         GetDItem(gSettingsDialog, SOUND_ON_BOX, itemType, itemHandle, itemRect);
  92.         if GetCtlValue(ControlHandle(itemHandle)) = ON then
  93.             gMyNMRec.nmSound := GetResource('snd ', BASE_RES_ID)
  94.         else
  95.             gMyNMRec.nmSound := nil;
  96.  
  97.         GetDItem(gSettingsDialog, ALERT_ON_BOX, itemType, itemHandle, itemRect);
  98.         if GetCtlValue(ControlHandle(itemHandle)) = ON then
  99.             begin
  100.                 MoveHHi(Handle(gNotifyStrH));
  101.                 HLock(Handle(gNotifyStrH));
  102.                 gMyNMRec.nmStr := gNotifyStrH^;
  103.             end
  104.         else
  105.             gMyNMRec.nmStr := nil;
  106.  
  107.         dummy := NMInstall(@gMyNMRec);
  108.         EnableItem(gFileMenu, KILL_ITEM);
  109.         gNotify_set := TRUE;
  110.     end;
  111.  
  112.  
  113. {-------------------------------->    CountDown    <---}
  114.  
  115.     procedure CountDown (numSecs: LONGINT);
  116.         var
  117.             myTime, oldTime, difTime: LONGINT;
  118.             myTimeString: Str255;
  119.             countDownWindow: WindowPtr;
  120.     begin
  121.         countDownWindow := GetNewWindow(BASE_RES_ID, nil, WindowPtr(-1));
  122.         SetPort(countDownWindow);
  123.         ShowWindow(countDownWindow);
  124.         TextFace([bold]);
  125.         TextSize(24);
  126.  
  127.         GetDateTime(myTime);
  128.         oldTime := myTime;
  129.  
  130.         if gSeconds_or_minutes = minutes then
  131.             numSecs := numSecs * SECONDS_PER_MINUTE;
  132.  
  133.         gCounting := TRUE;
  134.  
  135.         while (numSecs > 0) and gCounting do
  136.             begin
  137.                 HandleEvent;
  138.                 if gCounting then
  139.                     begin
  140.                         MoveTo(LEFT, TOP);
  141.                         GetDateTime(myTime);
  142.                         if myTime <> oldTime then
  143.                             begin
  144.                                 difTime := myTime - oldTime;
  145.                                 numSecs := numSecs - difTime;
  146.                                 oldTime := myTime;
  147.                                 NumToString(numSecs, myTimeString);
  148.                                 EraseRect(countDownWindow^.portRect);
  149.                                 DrawString(myTimeString);
  150.                             end;
  151.                     end;
  152.             end;
  153.  
  154.         if gCounting then
  155.             SetNotification;
  156.  
  157.         gCounting := FALSE;
  158.         HideWindow(countDownWindow);
  159.     end;
  160.  
  161.  
  162. {-------------------------------->    RestoreSettings    <---}
  163.  
  164.     procedure RestoreSettings;
  165.         var
  166.             itemType: INTEGER;
  167.             itemRect: Rect;
  168.             itemHandle: Handle;
  169.     begin
  170.         GetDItem(gSettingsDialog, TIME_FIELD, itemType, itemHandle, itemRect);
  171.         SetIText(itemHandle, savedSettings.timeString);
  172.         GetDItem(gSettingsDialog, SOUND_ON_BOX, itemType, itemHandle, itemRect);
  173.         SetCtlValue(ControlHandle(itemHandle), savedSettings.sound);
  174.         GetDItem(gSettingsDialog, ICON_ON_BOX, itemType, itemHandle, itemRect);
  175.         SetCtlValue(ControlHandle(itemHandle), savedSettings.icon);
  176.         GetDItem(gSettingsDialog, ALERT_ON_BOX, itemType, itemHandle, itemRect);
  177.         SetCtlValue(ControlHandle(itemHandle), savedSettings.alert);
  178.         GetDItem(gSettingsDialog, SECS_RADIO, itemType, itemHandle, itemRect);
  179.         SetCtlValue(ControlHandle(itemHandle), savedSettings.secsRadio);
  180.         GetDItem(gSettingsDialog, MINS_RADIO, itemType, itemHandle, itemRect);
  181.         SetCtlValue(ControlHandle(itemHandle), savedSettings.minsRadio);
  182.  
  183.         if savedSettings.secsRadio = ON then
  184.             begin
  185.                 GetDItem(gSettingsDialog, S_OR_M_FIELD, itemType, itemHandle, itemRect);
  186.                 SetIText(itemHandle, 'seconds');
  187.             end
  188.         else
  189.             begin
  190.                 GetDItem(gSettingsDialog, S_OR_M_FIELD, itemType, itemHandle, itemRect);
  191.                 SetIText(itemHandle, 'minutes');
  192.             end;
  193.     end;
  194.  
  195.  
  196. {-------------------------------->    SaveSettings    <---}
  197.  
  198.     procedure SaveSettings;
  199.         var
  200.             itemType: INTEGER;
  201.             itemRect: Rect;
  202.             itemHandle: Handle;
  203.     begin
  204.         GetDItem(gSettingsDialog, TIME_FIELD, itemType, itemHandle, itemRect);
  205.         GetIText(itemHandle, savedSettings.timeString);
  206.         GetDItem(gSettingsDialog, SOUND_ON_BOX, itemType, itemHandle, itemRect);
  207.         savedSettings.sound := GetCtlValue(ControlHandle(itemHandle));
  208.         GetDItem(gSettingsDialog, ICON_ON_BOX, itemType, itemHandle, itemRect);
  209.         savedSettings.icon := GetCtlValue(ControlHandle(itemHandle));
  210.         GetDItem(gSettingsDialog, ALERT_ON_BOX, itemType, itemHandle, itemRect);
  211.         savedSettings.alert := GetCtlValue(ControlHandle(itemHandle));
  212.         GetDItem(gSettingsDialog, SECS_RADIO, itemType, itemHandle, itemRect);
  213.         savedSettings.secsRadio := GetCtlValue(ControlHandle(itemHandle));
  214.         GetDItem(gSettingsDialog, MINS_RADIO, itemType, itemHandle, itemRect);
  215.         savedSettings.minsRadio := GetCtlValue(ControlHandle(itemHandle));
  216.     end;
  217.  
  218.  
  219. {-------------------------------->    HandleDialog    <---}
  220.  
  221.     procedure HandleDialog;
  222.         var
  223.             dialogDone: BOOLEAN;
  224.             itemHit, itemType: INTEGER;
  225.             alarmDelay: LONGINT;
  226.             delayString: Str255;
  227.             itemRect: Rect;
  228.             itemHandle: Handle;
  229.     begin
  230.         ShowWindow(gSettingsDialog);
  231.         SaveSettings;
  232.  
  233.         dialogDone := FALSE;
  234.         while dialogDone = FALSE do
  235.             begin
  236.                 ModalDialog(nil, itemHit);
  237.                 case itemHit of
  238.                     SAVE_BUTTON: 
  239.                         begin
  240.                             HideWindow(gSettingsDialog);
  241.                             dialogDone := TRUE;
  242.                         end;
  243.                     CANCEL_BUTTON: 
  244.                         begin
  245.                             HideWindow(gSettingsDialog);
  246.                             RestoreSettings;
  247.                             dialogDone := TRUE;
  248.                         end;
  249.                     SOUND_ON_BOX: 
  250.                         begin
  251.                             GetDItem(gSettingsDialog, SOUND_ON_BOX, itemType, itemHandle, itemRect);
  252.                             if GetCtlValue(ControlHandle(itemHandle)) = ON then
  253.                                 SetCtlValue(ControlHandle(itemHandle), OFF)
  254.                             else
  255.                                 SetCtlValue(ControlHandle(itemHandle), ON);
  256.                         end;
  257.                     ICON_ON_BOX: 
  258.                         begin
  259.                             GetDItem(gSettingsDialog, ICON_ON_BOX, itemType, itemHandle, itemRect);
  260.                             if GetCtlValue(ControlHandle(itemHandle)) = ON then
  261.                                 SetCtlValue(ControlHandle(itemHandle), OFF)
  262.                             else
  263.                                 SetCtlValue(ControlHandle(itemHandle), ON);
  264.                         end;
  265.                     ALERT_ON_BOX: 
  266.                         begin
  267.                             GetDItem(gSettingsDialog, ALERT_ON_BOX, itemType, itemHandle, itemRect);
  268.                             if GetCtlValue(ControlHandle(itemHandle)) = ON then
  269.                                 SetCtlValue(ControlHandle(itemHandle), OFF)
  270.                             else
  271.                                 SetCtlValue(ControlHandle(itemHandle), ON);
  272.                         end;
  273.                     SECS_RADIO: 
  274.                         begin
  275.                             gSeconds_or_minutes := seconds;
  276.                             GetDItem(gSettingsDialog, MINS_RADIO, itemType, itemHandle, itemRect);
  277.                             SetCtlValue(ControlHandle(itemHandle), OFF);
  278.                             GetDItem(gSettingsDialog, SECS_RADIO, itemType, itemHandle, itemRect);
  279.                             SetCtlValue(ControlHandle(itemHandle), ON);
  280.                             GetDItem(gSettingsDialog, S_OR_M_FIELD, itemType, itemHandle, itemRect);
  281.                             SetIText(itemHandle, 'seconds');
  282.                             GetDItem(gSettingsDialog, TIME_FIELD, itemType, itemHandle, itemRect);
  283.                             SetIText(itemHandle, gDefaultSecsH^^);
  284.                         end;
  285.                     MINS_RADIO: 
  286.                         begin
  287.                             gSeconds_or_minutes := minutes;
  288.                             GetDItem(gSettingsDialog, SECS_RADIO, itemType, itemHandle, itemRect);
  289.                             SetCtlValue(ControlHandle(itemHandle), OFF);
  290.                             GetDItem(gSettingsDialog, MINS_RADIO, itemType, itemHandle, itemRect);
  291.                             SetCtlValue(ControlHandle(itemHandle), ON);
  292.                             GetDItem(gSettingsDialog, S_OR_M_FIELD, itemType, itemHandle, itemRect);
  293.                             SetIText(itemHandle, 'minutes');
  294.                             GetDItem(gSettingsDialog, TIME_FIELD, itemType, itemHandle, itemRect);
  295.                             SetIText(itemHandle, gDefaultMinsH^^);
  296.                         end;
  297.                 end;
  298.             end;
  299.     end;
  300.  
  301.  
  302. {-------------------------------->    HandleFileChoice    <---}
  303.  
  304.     procedure HandleFileChoice (theItem: INTEGER);
  305.         var
  306.             timeString: Str255;
  307.             countDownTime: LONGINT;
  308.             itemType: INTEGER;
  309.             itemRect: Rect;
  310.             itemHandle: Handle;
  311.             dummy: OSErr;
  312.     begin
  313.         case theItem of
  314.             CHANGE_ITEM: 
  315.                 HandleDialog;
  316.             START_STOP_ITEM: 
  317.                 if gCounting then
  318.                     begin
  319.                         SetItem(gFileMenu, theItem, 'Start Countdown');
  320.                         gCounting := FALSE;
  321.                     end
  322.                 else
  323.                     begin
  324.                         HiliteMenu(0);
  325.                         GetDItem(gSettingsDialog, TIME_FIELD, itemType, itemHandle, itemRect);
  326.                         GetIText(itemHandle, timeString);
  327.                         StringToNum(timeString, countDownTime);
  328.  
  329.                         DisableItem(gFileMenu, CHANGE_ITEM);
  330.                         SetItem(gFileMenu, theItem, 'Stop Countdown');
  331.                         CountDown(countDownTime);
  332.                         EnableItem(gFileMenu, CHANGE_ITEM);
  333.                         SetItem(gFileMenu, theItem, 'Start Countdown');
  334.                     end;
  335.             KILL_ITEM: 
  336.                 begin
  337.                     dummy := NMRemove(@gMyNMRec);
  338.                     HUnlock(Handle(gNotifyStrH));
  339.                     DisableItem(gFileMenu, KILL_ITEM);
  340.                     gNotify_set := FALSE;
  341.                 end;
  342.             QUIT_ITEM: 
  343.                 begin
  344.                     gCounting := FALSE;
  345.                     gDone := TRUE;
  346.                     if gNotify_set then
  347.                         dummy := NMRemove(@gMyNMRec);
  348.                 end;
  349.         end;
  350.     end;
  351.  
  352.  
  353. {-------------------------------->    HandleAppleChoice    <---}
  354.  
  355.     procedure HandleAppleChoice (theItem: INTEGER);
  356.         var
  357.             accName: Str255;
  358.             accNumber, itemNumber, dummy: INTEGER;
  359.     begin
  360.         case theItem of
  361.             ABOUT_ITEM: 
  362.                 dummy := NoteAlert(ABOUT_ALERT, nil);
  363.             otherwise
  364.                 begin
  365.                     GetItem(gAppleMenu, theItem, accName);
  366.                     accNumber := OpenDeskAcc(accName);
  367.                 end;
  368.         end;
  369.     end;
  370.  
  371.  
  372. {-------------------------------->    HandleMenuChoice    <---}
  373.  
  374.     procedure HandleMenuChoice (menuChoice: LONGINT);
  375.         var
  376.             theMenu, theItem: INTEGER;
  377.     begin
  378.         if menuChoice <> 0 then
  379.             begin
  380.                 theMenu := HiWord(menuChoice);
  381.                 theItem := LoWord(menuChoice);
  382.  
  383.                 case theMenu of
  384.                     APPLE_MENU_ID: 
  385.                         HandleAppleChoice(theItem);
  386.                     FILE_MENU_ID: 
  387.                         HandleFileChoice(theItem);
  388.                 end;
  389.  
  390.                 HiliteMenu(0);
  391.             end;
  392.     end;
  393.  
  394.  
  395. {-------------------------------->    HandleMouseDown    <---}
  396.  
  397.     procedure HandleMouseDown;
  398.         var
  399.             whichWindow: WindowPtr;
  400.             thePart: INTEGER;
  401.             menuChoice, windSize: LONGINT;
  402.     begin
  403.         thePart := FindWindow(gTheEvent.where, whichWindow);
  404.         case thePart of
  405.             inMenuBar: 
  406.                 begin
  407.                     menuChoice := MenuSelect(gTheEvent.where);
  408.                     HandleMenuChoice(menuChoice);
  409.                 end;
  410.             inSysWindow: 
  411.                 SystemClick(gTheEvent, whichWindow);
  412.             inDrag: 
  413.                 DragWindow(whichWindow, gTheEvent.where, gDragRect);
  414.             inGoAway: 
  415.                 gDone := TRUE;
  416.         end;
  417.     end;
  418.  
  419.  
  420. {-------------------------------->    HandleEvent    <---}
  421.  
  422.     procedure HandleEvent;
  423.         var
  424.             theChar: CHAR;
  425.             dummy: BOOLEAN;
  426.     begin
  427.         dummy := WaitNextEvent(everyEvent, gTheEvent, MIN_SLEEP, nil);
  428.  
  429.         case gTheEvent.what of
  430.             mouseDown: 
  431.                 HandleMouseDown;
  432.             keyDown, autoKey: 
  433.                 begin
  434.                     theChar := CHR(BitAnd(gTheEvent.message, charCodeMask));
  435.                     if (BitAnd(gTheEvent.modifiers, cmdKey) <> 0) then
  436.                         HandleMenuChoice(MenuKey(theChar));
  437.                 end;
  438.         end;
  439.     end;
  440.  
  441.  
  442. {-------------------------------->    MainLoop    <---}
  443.  
  444.     procedure MainLoop;
  445.     begin
  446.         gDone := FALSE;
  447.         gCounting := FALSE;
  448.         gNotify_set := FALSE;
  449.  
  450.         while gDone = FALSE do
  451.             HandleEvent;
  452.     end;
  453.  
  454.  
  455. {-------------------------------->    NotifyInit    <---}
  456.  
  457.     procedure NotifyInit;
  458.     begin
  459.         gNotifyStrH := GetString(BASE_RES_ID);
  460.         gMyNMRec.qType := nmType;
  461.         gMyNMRec.nmMark := MARK_APPLICATION;
  462.         gMyNMRec.nmResp := nil;
  463.     end;
  464.  
  465.  
  466. {-------------------------------->    SetUpDragRect    <---}
  467.  
  468.     procedure SetUpDragRect;
  469.     begin
  470.         gDragRect := screenBits.bounds;
  471.         gDragRect.left := gDragRect.left + DRAG_THRESHOLD;
  472.         gDragRect.right := gDragRect.right - DRAG_THRESHOLD;
  473.         gDragRect.bottom := gDragRect.bottom - DRAG_THRESHOLD;
  474.     end;
  475.  
  476.  
  477. {-------------------------------->    MenuBarInit    <---}
  478.  
  479.     procedure MenuBarInit;
  480.         var
  481.             myMenuBar: Handle;
  482.     begin
  483.         myMenuBar := GetNewMBar(BASE_RES_ID);
  484.         SetMenuBar(myMenuBar);
  485.         gAppleMenu := GetMHandle(APPLE_MENU_ID);
  486.         AddResMenu(gAppleMenu, 'DRVR');
  487.         gFileMenu := GetMHandle(FILE_MENU_ID);
  488.         DrawMenuBar;
  489.     end;
  490.  
  491.  
  492. {-------------------------------->    DialogInit    <---}
  493.  
  494.     procedure DialogInit;
  495.         var
  496.             itemType: INTEGER;
  497.             itemRect: Rect;
  498.             itemHandle: Handle;
  499.     begin
  500.         gDefaultSecsH := GetString(DEFAULT_SECS_ID);
  501.         gDefaultMinsH := GetString(DEFAULT_MINS_ID);
  502.  
  503.         gSettingsDialog := GetNewDialog(BASE_RES_ID, nil, WindowPtr(-1));
  504.         GetDItem(gSettingsDialog, SECS_RADIO, itemType, itemHandle, itemRect);
  505.         SetCtlValue(ControlHandle(itemHandle), ON);
  506.         GetDItem(gSettingsDialog, SOUND_ON_BOX, itemType, itemHandle, itemRect);
  507.         SetCtlValue(ControlHandle(itemHandle), ON);
  508.         GetDItem(gSettingsDialog, ICON_ON_BOX, itemType, itemHandle, itemRect);
  509.         SetCtlValue(ControlHandle(itemHandle), ON);
  510.         GetDItem(gSettingsDialog, ALERT_ON_BOX, itemType, itemHandle, itemRect);
  511.         SetCtlValue(ControlHandle(itemHandle), ON);
  512.  
  513.         gSeconds_or_minutes := seconds;
  514.     end;
  515.  
  516.  
  517. {-------------------------------->    Sys6OrLater    <---}
  518.  
  519.     function Sys6OrLater: BOOLEAN;
  520.         var
  521.             status: OSErr;
  522.             SysEnvData: SysEnvRec;
  523.             dummy: INTEGER;
  524.     begin
  525.         status := SysEnvirons(SYS_VERSION, SysEnvData);
  526.         if (status <> noErr) or (SysEnvData.systemVersion < $0600) then
  527.             begin
  528.                 dummy := StopAlert(BAD_SYS_ALERT, nil);
  529.                 Sys6OrLater := FALSE;
  530.             end
  531.         else
  532.             Sys6OrLater := TRUE;
  533.     end;
  534.  
  535.  
  536. {-------------------------------->    Reminder    <---}
  537.  
  538. begin
  539.     if Sys6OrLater then
  540.         begin
  541.             DialogInit;
  542.             MenuBarInit;
  543.             SetUpDragRect;
  544.             NotifyInit;
  545.  
  546.             MainLoop;
  547.         end;
  548. end.